import { Callout } from "nextra-theme-docs";

# appsettings.json の設定

`appsettings.json` ファイルは GZCTF のコア設定ファイルで、コンテナ内にマウントすることで設定します。この記事では、設定ファイルの各フィールドの意味を説明します。

<Callout type="info">

`appsettings.json` の更新は、GZCTF サービスを再起動するたびに反応されます。

</Callout>

## 設定ファイルの構造

以下に完全な設定ファイルの例を示します：

```json
{
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=<Database Password>"
    // redis is optional
    //"RedisCache": "cache:6379,password=<Redis Password>"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "Loki": {
      "Enable": true,
      "EndpointUri": "http://loki:3100",
      "Labels": [
        {
          "Key": "app",
          "Value": "gzctf"
        }
      ],
      "PropertiesAsLabels": ["app"],
      "Credentials": {
        "Login": "login",
        "Password": "password"
      },
      "Tenant": "my-tenant",
      "MinimumLevel": "Trace"
    }
  },
  "Telemetry": {
    "Prometheus": {
      "Enable": false,
      "Port": 3000,
      "TotalNameSuffixForCounters": false
    },
    "OpenTelemetry": {
      "Enable": false,
      "Protocol": "Grpc",
      "EndpointUri": "http://jaeger-collector:4317"
    },
    "AzureMonitor": {
      "Enable": false,
      "ConnectionString": "InstrumentationKey=12345678-abcd-abcd-abcd-12345678..."
    },
    "Console": {
      "Enable": false
    }
  },
  "EmailConfig": {
    "SenderAddress": "",
    "SenderName": "",
    "UserName": "",
    "Password": "",
    "Smtp": {
      "Host": "localhost",
      "Port": 587,
      "BypassCertVerify": false
    }
  },
  "XorKey": "<Random Key Str>",
  "ContainerProvider": {
    "Type": "Docker", // or "Kubernetes"
    "PortMappingType": "Default",
    "EnableTrafficCapture": false,
    "PublicEntry": "ctf.example.com", // or "xxx.xxx.xxx.xxx"
    "DockerConfig": {
      // optional
      "SwarmMode": false,
      "ChallengeNetwork": "",
      "Uri": "unix:///var/run/docker.sock",
      "UserName": "",
      "Password": ""
    },
    "KubernetesConfig": {
      // optional
      "Namespace": "gzctf-challenges",
      "ConfigPath": "kube-config.yaml",
      "AllowCIDR": [
        // allow the cluster CIDR for LB
        "10.0.0.0/8"
      ],
      "DNS": [
        // custom DNS to avoid cluster DNS
        "8.8.8.8",
        "223.5.5.5"
      ]
    }
  },
  "RequestLogging": false,
  "DisableRateLimit": false,
  "RegistryConfig": {
    "UserName": "",
    "Password": "",
    "ServerAddress": ""
  },
  "CaptchaConfig": {
    "Provider": "None",
    "SiteKey": "...",
    "SecretKey": "...",
    "GoogleRecaptcha": {
      "VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify",
      "RecaptchaThreshold": "0.5"
    }
  },
  "ForwardedOptions": {
    "ForwardedHeaders": 5, // a flag enum, see following link
    "ForwardLimit": 1,
    "ForwardedForHeaderName": "X-Forwarded-For",
    // use the following options to allow proxy
    "TrustedNetworks": ["10.0.0.0/8"],
    "TrustedProxies": ["10.0.0.1"]
  },
  "Kestrel": {
    "Endpoints": {
      "Web": {
        "Url": "http://*:8080"
      },
      "Prometheus": {
        "Url": "http://*:3000"
      }
    },
    "Limits": {
      "MaxResponseBufferSize": 2048,
      "MaxRequestBufferSize": 1048576,
      "MaxRequestLineSize": 8192,
      "MaxRequestHeadersTotalSize": 32768,
      "MaxRequestHeaderCount": 100,
      "MaxRequestBodySize": 27262946,
      "KeepAliveTimeout": "0.0:5:0",
      "RequestHeadersTimeout": "0.0:5:0",
      "MaxConcurrentConnections": null,
      "MaxConcurrentUpgradedConnections": null
    },
    "AddServerHeader": true,
    "AllowResponseHeaderCompression": true,
    "AllowSynchronousIO": false,
    "AllowAlternateSchemes": false,
    "DisableStringReuse": false,
    "ConfigurationLoader": null
  }
}
```

## コア機能の設定フィールド

### ConnectionStrings

ここではデータベース接続文字列を設定します。`Database`は必須項目で、`RedisCache`はオプションです。

GZCTF は PostgreSQL をバックエンドデータベースおよびデータ永続化に使用し、Redis をキャッシュおよびメッセージキューとして使用します。単一インスタンスのデプロイでは Redis は必須ではなく、GZCTF のメモリキャッシュを直接使用できます。複数インスタンスのデプロイでは、Redis は必須であり、共有キャッシュおよび SignalR の Scale-Out ブロードキャストとして使用されます。

<Callout type="info">

GZCTF はデータベースとして PostgreSQL のみをサポートしており、MySQL などの他のデータベースはサポートしていません。設定ファイルに正しいデータベース接続文字列を記入してください。

</Callout>

### Logging

ロギングレベルとスコープを設定することができます。さらに、GZCTF は Loki サーバーへのログ送信もサポートしています。

- **LogLevel**: 名前空間ごとの最小ロギングレベル。
- **Loki**: Loki サーバーの設定。

  - **Enable**: 有効にするかどうか。
  - **EndpointUri**: Loki サーバーの URI。
  - **Labels**: 任意。グローバルログイベントラベル。
  - **PropertiesAsLabels**: 任意。Loki のラベルにマップするべきプロパティのリスト。
  - **Credentials**: 任意。基本認証に使用される資格情報。
  - **Tenant**: 任意。Loki サーバーへのログ送信に使用されるテナント ID。
  - **MinimumLevel**: 任意。最小ロギングレベル。

利用可能なロギングレベル: Trace, Debug, Information, Warning, Error, Critical, None。

### Telemetry

GZCTF はメトリクスと分散トレーシングをサポートしています。使用するプロバイダーを設定できます。

- **Prometheus**: Prometheus エンドポイント。

  - **Enable**: 有効にするかどうか。
  - **Port**: 任意。Prometheus の `/metrics` エンドポイントがリッスンするポート。これが設定されている場合、サーバーが指定されたポートを正常にリッスンするようにするには、`Kestrel.Endpoints` を手動で追加設定する必要があります。
  - **TotalNameSuffixForCounters**: 任意。カウンタに `_total` サフィックスを含めるかどうか。

- **OpenTelemetry**: メトリクスとトレーシングデータを OpenTelemetry にエクスポートします。

  - **Enable**: 有効にするかどうか。
  - **Protocol**: `Grpc` または `HttpProtobuf`。
  - **EndpointUri**: テレメトリーデーターがプッシュされる OpenTelemetry エンドポイント URI。

- **AzureMonitor**: メトリクスとトレーシングデータを ApplicationInsights にエクスポートします。

  - **Enable**: 有効にするかどうか。
  - **ConnectionString**: 接続文字列。

- **Console**: トレーシングデータをコンソールにエクスポートします。

  - **Enable**: 有効にするかどうか。

### EmailConfig

ここではメール送信に関する情報を設定します。メールでの登録やその他のメール機能を使用する場合、この項目は必須です。

- **SenderAddress:** 送信者のメールアドレス
- **SenderName:** 送信者の名前
- **UserName:** SMTP サーバーのユーザー名
- **Password:** SMTP サーバーのパスワード
- **Smtp:** SMTP サーバーのアドレスとポート
- **BypassCertVerify:** 証明書の検証をバイパスするかどうか

<Callout type="info">

一部のクラウドサービスプロバイダの制限により、465 ポートを使用してメールを送信できない場合があります。その場合は、587 ポートを試してみてください。

</Callout>

### XorKey

ここでは暗号化キーを設定します。これは、データベース内のゲームの秘密鍵情報を暗号化するために使用されます。任意の長さの任意の文字列を使用できます。

### ContainerProvider

ここではコンテナバックエンドを設定します。これは、ゲームで動的にコンテナを作成するための必須項目です。

- **Type:** コンテナバックエンドのタイプ。`Docker`または`Kubernetes`を選択できます。
- **PublicEntry:** コンテナバックエンドの公開アドレス。これは、ゲームのアクセスアドレスを生成し、参加チームに表示するために使用されます。
- **PortMappingType:** ポートマッピングのタイプ。`Default`または`PlatformProxy`を選択できます。
- **EnableTrafficCapture:** トラフィックキャプチャを有効にするかどうか。`PortMappingType`が`PlatformProxy`に設定されている場合のみ使用できます。有効にすると、`/app/files/capture`ディレクトリにトラフィックが記録されます。

#### Docker

- **SwarmMode:** Swarm モードかどうか。Swarm モードの場合、Swarm API を使用して管理します。

  <Callout type="warning">

  Docker Swarm はもはや活発なプロジェクトではなく、k8s と比較してセキュリティ機能に大きな差があるため、使用は推奨されません。

  </Callout>

- **Uri:** Docker API Server のアドレス

  - ローカルの docker を使用する場合は、Uri を空にし、`/var/run/docker.sock`をコンテナの対応する位置にマウントします。
  - 外部の docker を使用する場合は、Uri を対応する docker API Server に指定します。**外部 API の認証はまだ実装されていませんので、このデプロイ方法は推奨されません。**

- **ChallengeNetwork:** チャレンジコンテナが所属するネットワークを指定します。指定しない場合は、デフォルトのネットワークを使用します。

- **UserName, Password:** Docker API Basic Auth のユーザー名とパスワード。オプションです。

#### Kubernetes

- **Namespace:** Kubernetes の名前空間。チャレンジインスタンスを作成するための名前空間で、デフォルトは`gzctf-challenges`です。
- **ConfigPath:** Kubernetes の設定ファイルのパス。クラスタに接続するために使用します。デフォルトは`kube-config.yaml`です。
- **AllowCIDR:** Pod へのアクセスを許可する CIDR ホワイトリスト。
- **DNS:** クラスタ DNS を避けるためのカスタム DNS サーバーリスト。

デフォルトの動作は、クラスタ接続設定を`kube-config.yaml`ファイルに入れ、それを`/app`ディレクトリにマウントすることです。実験的な機能は、行動を理解していない限り、変更しないでください。

<Callout type="info">

`kube-config.yaml`ファイルの`server`フィールドを変更し、クラスタの API Server アドレスを指定することに注意してください。クラスタのデフォルトアドレスは通常`https://127.0.0.1:6443`で、クラスタの実際のアドレスに変更する必要があります。

</Callout>

<Callout type="info" emoji="👾">

ネットワークポリシーを満たすために、GZCTF はチャレンジの Namespace に`gzctf-policy`という名前の NetworkPolicy を作成してアクセスを制限します。GZCTF はこの NetworkPolicy が既に存在するかどうかを自動的に検出し、存在する場合は再作成しません。そのため、ネットワークポリシーをカスタマイズするには、この NetworkPolicy を作成または編集してください。

</Callout>

### RequestLogging

ここでは、リクエストログの記録を有効にするかどうかを設定します。有効にすると、ログに各リクエストの詳細情報が出力されます。この出力には静的ファイルのリクエストは含まれません。

### DisableRateLimit

ここでは、リクエストの頻度制限を有効にするかどうかを設定します。有効にすると、事前に設定したルールに基づいて、各 IP と API のリクエスト頻度が制限されます。

### RegistryConfig

ここでは Docker Registry のユーザー名とパスワードを設定します。これは、ゲームで動的にコンテナを作成する際にイメージをプルするための認証で、オプションです。

- **UserName:** Docker Registry のユーザー名
- **Password:** Docker Registry のパスワード
- **ServerAddress:** Docker Registry のアドレス。`https://`のプレフィックスは含めないでください。

<Callout type="info">

パスワードに特殊文字（`":@`など、ただし`_`は使用可能）が含まれていないことを確認してください。そうでないと、テンプレートインジェクションの問題が発生し、Secret の作成に失敗する可能性があります。

</Callout>

### CaptchaConfig

ここでは、キャプチャ関連の情報を設定します。これは、登録、アカウントの回復、ログイン時のキャプチャの検証に使用されます。オプションです。

- **Provider:** キャプチャのプロバイダ。`None`、`GoogleRecaptcha`、または`CloudflareTurnstile`を選択できます。
- **SiteKey:** キャプチャの Sitekey
- **SecretKey:** キャプチャの Secretkey

#### GoogleRecaptcha

Google Recaptcha v3 の関連情報を設定します。オプションです。

- **VerifyAPIAddress:** Google Recaptcha の検証 API アドレス
- **RecaptchaThreshold:** Google Recaptcha の閾値。キャプチャが有効かどうかを判断するために使用します。

### ForwardedOptions

ここでは、リバースプロキシの関連情報を設定します。これは、実際の IP アドレスを取得するために使用されます。オプションです。

- **ForwardedHeaders:** リバースプロキシが転送するヘッダーの列挙型。デフォルトは`5`を使用してください。詳細は [ForwardedHeaders 列挙型](https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.aspnetcore.httpoverrides.forwardedheaders)を参照してください。
- **ForwardLimit:** リバースプロキシの層数制限
- **ForwardedForHeaderName:** リバースプロキシの IP アドレスヘッダー名
- **TrustedNetworks:** リバースプロキシが信頼するネットワークのリスト。CIDR で表現します。
- **TrustedProxies:** リバースプロキシが信頼するプロキシのリスト。IP アドレスまたはドメイン名で表現します。

<Callout type="info">

リバースプロキシの信頼リストを無視し、任意の IP アドレスからのアクセスを許可したい場合は、[Linux および非 IIS のリバース プロキシのスキームを転送する](https://learn.microsoft.com/ja-jp/aspnet/core/host-and-deploy/proxy-load-balancer#forward-the-scheme-for-linux-and-non-iis-reverse-proxies)を参照し、環境変数`ASPNETCORE_FORWARDEDHEADERS_ENABLED`を`true`に設定してください。

</Callout>

他のフィールドについては、公式ドキュメントの説明を参照してください：[プロキシ サーバーとロード バランサーを使用するために ASP.NET Core を構成する](https://learn.microsoft.com/ja-jp/aspnet/core/host-and-deploy/proxy-load-balancer)および[ForwardedHeadersOptions クラス](https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.aspnetcore.builder.forwardedheadersoptions)

### Kestrel

Kestrel は GZCTF が内蔵して使用している Web サーバーです。この設定を利用すると、HTTP プロトコルを指定したり、リクエストのサイズ上限を変更したりと、Kestrel の動作を自由に制御することができます。

- **Endpoints**: Web サーバーがリッスンする URL。環境変数または起動パラメータを通じて設定することもできます。詳細については、[ASP.NET Core Kestrel Web サーバーのエンドポイントを構成する] (https://learn.microsoft.com/ja-jp/aspnet/core/fundamentals/servers/kestrel/endpoints) を参照してください。
- 他の設定フィールドについては、公式ドキュメントの`KestrelServerOptions`クラスの属性を参照してください：[KestrelServerOptions クラス](https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.aspnetcore.server.kestrel.core.kestrelserveroptions)。
